<!-- eslint-disable no-unused-vars -->
<template>
  <div class="reservation-list-container" :style="containerStyle">
    <!-- 搜索区域 -->
    <div v-if="showSearch && searchItems.length > 0" class="search-box">
      <el-form :inline="true" :model="searchData">
        <template v-for="(item, index) in searchItems" :key="getSearchItemKey(item, index)">
          <el-form-item :label="item.label" :prop="item.prop">
            <!-- 动态渲染组件 -->
            <template v-if="item.component === 'el-select'">
              <el-select
                v-model="searchData[item.prop]"
                v-bind="item.props"
                :placeholder="`请选择${item.label}`"
                clearable
                style="width: 180px"
              >
                <el-option
                  v-for="opt in item.props?.options || []"
                  :key="opt.value"
                  :label="opt.label"
                  :value="opt.value"
                />
              </el-select>
            </template>
            <template v-else-if="item.component === 'el-input'">
              <el-input
                v-model="searchData[item.prop]"
                v-bind="item.props"
                :placeholder="`请输入${item.label}`"
                clearable
                style="width: 180px"
              />
            </template>
            <template v-else-if="item.component === 'el-date-picker'">
              <el-date-picker
                v-bind="item.props"
                v-model="searchData[item.prop]"
                type="datetimerange"
                format="YYYY-MM-DD HH:mm:ss"
                date-format="YYYY/MM/DD"
                value-format="YYYY-MM-DD HH:mm:ss"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
                :placeholder="`请选择${item.label}`"
                clearable
              />
            </template>
          </el-form-item>
        </template>
        <el-button v-debounce="handleSearch" type="primary" :loading="searchLoading">
          <el-icon><Search /></el-icon>
          <span class="m-l-10">查询</span>
        </el-button>
        <el-button v-if="showResetButton" v-debounce="handleReset">
          <el-icon><Refresh /></el-icon>
          <span class="m-l-10">重置</span>
        </el-button>
      </el-form>
    </div>

    <!-- 操作按钮区域 -->
    <div v-if="showAction && actionButtons.length > 0" class="action-box">
      <template v-for="(btn, index) in actionButtons" :key="btn.text || index">
        <el-button
          v-debounce="() => btn.handler()"
          :type="btn.type || 'primary'"
          v-bind="btn.props || {}"
          :loading="btn.loading"
        >
          <template v-if="btn.icon">
            <el-icon><component :is="btn.icon" /></el-icon>
            <span v-if="btn.text" class="m-l-10">{{ btn.text }}</span>
          </template>
          <template v-else>
            {{ btn.text }}
          </template>
        </el-button>
      </template>
      <slot name="action-buttons"></slot>
    </div>

    <!-- 表格区域 -->
    <div class="table-box">
      <el-table
        v-loading="loading"
        :data="tableData"
        :cell-style="cellStyle"
        :header-cell-style="headerCellStyle"
        :row-class-name="rowClassName"
        :border="border"
        :stripe="stripe"
        :row-key="rowKey"
        @selection-change="handleSelectionChange"
        @sort-change="handleSortChange"
      >
        <!-- 选择列 -->
        <el-table-column
          v-if="showSelection"
          type="selection"
          width="55"
          :reserve-selection="reserveSelection"
        />

        <!-- 序号列 -->
        <el-table-column v-if="showIndex" type="index" label="序号" width="60" />

        <!-- 动态列 -->
        <template v-for="column in columns" :key="column.prop || column.label">
          <el-table-column
            :prop="column.prop"
            :label="column.label"
            :width="column.width"
            :min-width="column.minWidth"
            :fixed="column.fixed"
            :sortable="column.sortable"
            :formatter="column.formatter"
            :show-overflow-tooltip="column.showTooltip !== false"
          >
            <template v-if="column.slot || column.render" #default="scope">
              <slot v-if="column.slot" :name="column.slot" v-bind="scope"></slot>
              <component :is="column.render" v-else-if="column.render" v-bind="scope" />
            </template>
          </el-table-column>
        </template>

        <!-- 操作列 -->
        <el-table-column
          v-if="showOperation && (operationButtons.length > 0 || hasOperationSlot)"
          label="操作"
          :width="operationWidth"
          :fixed="operationFixed"
        >
          <template #default="scope">
            <div class="operation-btns">
              <template v-for="(btn, index) in operationButtons" :key="btn.text || index">
                <el-button
                  v-debounce="() => btn.handler && btn.handler(scope.row)"
                  link
                  :type="btn.type || 'primary'"
                  v-bind="btn.props || {}"
                >
                  <template v-if="btn.icon">
                    <el-icon><component :is="btn.icon" /></el-icon>
                    <span v-if="btn.text" class="m-l-10">{{ btn.text }}</span>
                  </template>
                  <template v-else>
                    {{ btn.text }}
                  </template>
                </el-button>
              </template>
              <slot name="operation" v-bind="scope"></slot>
            </div>
          </template>
        </el-table-column>
      </el-table>

      <!-- 分页 -->
      <div v-if="showPagination" class="pagination-box">
        <el-pagination
          :current-page="currentPage"
          :page-size="pageSize"
          :page-sizes="pageSizes"
          :total="total"
          :layout="paginationLayout"
          :background="paginationBackground"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, computed, useSlots } from "vue";
import { Search, Refresh } from "@element-plus/icons-vue";
import type { Component } from "vue";

interface SearchItem {
  label: string;
  prop: string;
  component?: string | Component;
  props?: Record<string, any>;
  events?: Record<string, any>;
  defaultValue?: any;
}

interface TableColumn {
  prop?: string;
  label: string;
  width?: string | number;
  minWidth?: string | number;
  fixed?: boolean | "left" | "right";
  sortable?: boolean | "custom";
  slot?: string;
  render?: Component;
  showTooltip?: boolean;
  formatter?: (_row: any, _column: any, _cellValue: any, _index: number) => string | VNode;
}

interface ActionButton {
  text?: string;
  handler: () => void;
  type?: "primary" | "success" | "warning" | "danger" | "info" | "text"; // 明确类型
  props?: Record<string, any>;
  icon?: Component;
  loading?: boolean;
}

interface OperationButton {
  text?: string;
  type?: "primary" | "success" | "warning" | "danger" | "info" | "text";
  props?: Record<string, any>;
  icon?: Component | null; // 允许null
  handler?: (_row: any) => void; // 改为void
}
interface SortInfo {
  prop: string;
  order: "ascending" | "descending" | null;
}

const props = defineProps({
  // 容器样式
  containerStyle: {
    type: Object,
    default: () => ({
      background: "linear-gradient(180deg, #f0f5ff 0%, #fbfcfe 100%)",
      boxShadow: "inset 2px 1px 2px 1px #ffffff, 0px 4px 8px 0px #eaf0ff",
      borderRadius: "25px",
    }),
  },
  // 搜索相关配置
  showSearch: {
    type: Boolean,
    default: true,
  },
  searchItems: {
    type: Array as () => SearchItem[],
    default: () => [],
  },
  showResetButton: {
    type: Boolean,
    default: true,
  },
  searchLoading: {
    type: Boolean,
    default: false,
  },
  // 操作按钮相关
  showAction: {
    type: Boolean,
    default: true,
  },
  actionButtons: {
    type: Array as () => ActionButton[],
    default: () => [],
  },
  // 表格相关配置
  tableData: {
    type: Array,
    required: true,
    default: () => [],
  },
  columns: {
    type: Array as () => TableColumn[],
    required: true,
    default: () => [],
  },
  loading: {
    type: Boolean,
    default: false,
  },
  cellStyle: {
    type: [Object],
    default: () => ({ textAlign: "center" }),
  },
  headerCellStyle: {
    type: [Object],
    default: () => ({ textAlign: "center" }),
  },
  rowClassName: {
    type: [String],
    default: () => "",
  },
  border: {
    type: Boolean,
    default: false,
  },
  stripe: {
    type: Boolean,
    default: true,
  },
  tableHeight: {
    type: [String, Number],
    default: "",
  },
  maxHeight: {
    type: [String, Number],
    default: "",
  },
  rowKey: {
    type: [String],
    default: "",
  },
  defaultSort: {
    type: [String],
    default: null,
  },
  // 表格功能列
  showSelection: {
    type: Boolean,
    default: false,
  },
  reserveSelection: {
    type: Boolean,
    default: false,
  },
  showIndex: {
    type: Boolean,
    default: true,
  },
  indexMethod: {
    type: Function,
    default: (index: number) => index + 1,
  },
  showOperation: {
    type: Boolean,
    default: true,
  },
  operationWidth: {
    type: [String, Number],
    default: "200px",
  },
  operationFixed: {
    type: [Boolean, String],
    default: false,
  },
  operationButtons: {
    type: Array as () => OperationButton[],
    default: () => [],
  },
  // 分页相关
  showPagination: {
    type: Boolean,
    default: true,
  },
  currentPage: {
    type: Number,
    default: 1,
  },
  pageSize: {
    type: Number,
    default: 10,
  },
  pageSizes: {
    type: Array as () => number[],
    default: () => [10, 20, 30, 50],
  },
  total: {
    type: Number,
    default: 0,
  },
  paginationLayout: {
    type: String,
    default: "total, sizes, prev, pager, next, jumper",
  },
  paginationBackground: {
    type: Boolean,
    default: true,
  },
});

const emit = defineEmits([
  "add",
  "search",
  "reset",
  "cancel",
  "detail",
  "selection-change",
  "size-change",
  "current-change",
  "sort-change",
  "update:current-page",
  "update:page-size",
]);

const slots = useSlots();

// 搜索数据初始化
const searchData = ref<Record<string, any>>(
  props.searchItems.reduce(
    (acc, item) => {
      acc[item.prop] =
        item.defaultValue !== undefined
          ? item.defaultValue
          : item.component === "el-select"
            ? null
            : "";
      return acc;
    },
    {} as Record<string, any>
  )
);

// 检查是否有操作插槽
const hasOperationSlot = computed(() => !!slots.operation);

const getSearchItemKey = (item: SearchItem, index: number) => {
  return `${item.prop}-${index}`;
};

// 操作方法
const handleSearch = () => {
  emit("search", searchData.value);
};

const handleReset = () => {
  searchData.value = props.searchItems.reduce(
    (acc, item) => {
      acc[item.prop] =
        item.defaultValue !== undefined
          ? item.defaultValue
          : item.component === "el-select"
            ? null
            : "";
      return acc;
    },
    {} as Record<string, any>
  );
  emit("reset", searchData.value);
};

const handleSelectionChange = (selection: any[]) => {
  emit("selection-change", selection);
};

const handleSizeChange = (size: number) => {
  emit("update:page-size", size);
  emit("size-change", size);
};

const handleCurrentChange = (page: number) => {
  emit("update:current-page", page);
  emit("current-change", page);
};

const handleSortChange = (sortInfo: SortInfo) => {
  emit("sort-change", sortInfo);
};
</script>

<style lang="scss" scoped>
.reservation-list-container {
  width: 100%;
  height: calc(100vh - 116px);
  margin: 0 auto;
  padding: 0px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;

  .search-box {
    display: flex;
    align-items: flex-start;
    flex-wrap: wrap;
    gap: 12px;
    padding: 30px 25px;
    border-bottom: 1px solid #ffffff;

    .el-form {
      display: flex;
      flex-wrap: wrap;
      gap: 12px;

      .el-form-item {
        margin-right: 0;
        margin-bottom: 0;

        :deep(.el-select),
        :deep(.el-input) {
          width: 180px;
        }
      }
    }
  }

  .action-box {
    margin: 20px 0;
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    padding: 10px 25px;
  }

  .table-box {
    padding: 0 25px;
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;

    :deep(.el-table) {
      flex: 1;

      .el-table__body-wrapper {
        overflow-x: auto;
      }
    }

    .operation-btns {
      display: flex;
      justify-content: center;
      flex-wrap: wrap;
      gap: 8px;
    }

    .pagination-box {
      margin-top: 20px;
      padding-bottom: 40px;
      display: flex;
      justify-content: flex-end;
    }
  }

  .m-l-10 {
    margin-left: 10px;
  }
}
</style>
